package com.xiaozhichao.databafflesys.route.service;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xiaozhichao.databafflesys.common.domain.CommonConstant;
import com.xiaozhichao.databafflesys.common.domain.ExceptionEnums;
import com.xiaozhichao.databafflesys.common.domain.ResultVo;
import com.xiaozhichao.databafflesys.common.utils.ReqCompare;
import com.xiaozhichao.databafflesys.repository.model.BaffleFailTmp;
import com.xiaozhichao.databafflesys.repository.model.BaffleInterface;
import com.xiaozhichao.databafflesys.repository.model.BaffleMessage;
import com.xiaozhichao.databafflesys.repository.service.BaffleFailTmpService;
import com.xiaozhichao.databafflesys.repository.service.BaffleInterfaceService;
import com.xiaozhichao.databafflesys.repository.service.BaffleMessageService;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;

/**
 * @author:xiaozhichao
 * @date:2021/3/22
 */
@Service
public class RouteService {

    public Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    BaffleInterfaceService interfaceService;
    @Autowired
    BaffleMessageService messageService;
    @Autowired
    BaffleFailTmpService baffleFailTmpService;

    public String route(String code, String req) throws Exception{
        // 获取接口配置
        QueryWrapper<BaffleInterface> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(true,BaffleInterface::getUri,code);
        BaffleInterface one = interfaceService.getOne(queryWrapper);
        if(Objects.isNull(one)){
            return JSONObject.toJSONString(ResultVo.getResult(ExceptionEnums.DO_FAIL,"接口未配置"));
        }
        // 获取错误响应报文模板
        QueryWrapper<BaffleFailTmp> queryWrapperFail = new QueryWrapper<>();
        queryWrapperFail.lambda().eq(true,BaffleFailTmp::getInterfaceId,one.getId());
        BaffleFailTmp failTmp = baffleFailTmpService.getOne(queryWrapperFail);
        if(Objects.isNull(one)){
            return JSONObject.toJSONString(ResultVo.getResult(ExceptionEnums.DO_FAIL,"失败报文模板未配置"));
        }
        String failRes = FileUtil.readUtf8String(failTmp.getResTmpUrl());
        // 获取报文配置
        String reqType = one.getReqType();
        QueryWrapper<BaffleMessage> queryWrapperMessage = new QueryWrapper<>();
        queryWrapperMessage.lambda()
                .eq(true,BaffleMessage::getInterfaceId,one.getId());
        List<BaffleMessage> list = messageService.list(queryWrapperMessage);
        if(CollectionUtils.isEmpty(list)){
            return failRes.replace(CommonConstant.fail_res_msg,"接口请求响应关系未配置");
        }
        Iterator<BaffleMessage> mesIter = list.iterator();
        BaffleMessage target = null;
        while (mesIter.hasNext()){
            BaffleMessage next = mesIter.next();
            if(ReqCompare.compare(reqType,req,FileUtil.readUtf8String(next.getReqUrl()))){
                target = next;
                break;
            }
        }
        if(Objects.isNull(target)){
            return failRes.replace(CommonConstant.fail_res_msg,"接口请求未匹配到响应，请重新配置");
        }
        String result = FileUtil.readUtf8String(target.getResUrl());
        Thread.sleep(target.getTimeout());
        return result;
    }

    public void routeFile(String code, String req, HttpServletResponse response) throws Exception{
        // 获取接口配置
        QueryWrapper<BaffleInterface> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(true,BaffleInterface::getUri,code);
        BaffleInterface one = interfaceService.getOne(queryWrapper);
        if(Objects.isNull(one)){
            return;
        }

        // 获取报文配置
        String reqType = one.getReqType();
        QueryWrapper<BaffleMessage> queryWrapperMessage = new QueryWrapper<>();
        queryWrapperMessage.lambda()
                .eq(true,BaffleMessage::getInterfaceId,one.getId());
        List<BaffleMessage> list = messageService.list(queryWrapperMessage);
        if(CollectionUtils.isEmpty(list)){
            return;
        }
        Iterator<BaffleMessage> mesIter = list.iterator();
        BaffleMessage target = null;
        while (mesIter.hasNext()){
            BaffleMessage next = mesIter.next();
            if(ReqCompare.compare(reqType,req,FileUtil.readUtf8String(next.getReqUrl()))){
                target = next;
                break;
            }
        }
        if(Objects.isNull(target)){
            return;
        }
        final String resUrl = target.getResUrl();
        byte[] bytes = FileUtil.readBytes(resUrl);
        Thread.sleep(target.getTimeout());
        response.reset();
        response.setContentType("application/octet-stream;charset=utf-8");
        response.setHeader(
                "Content-disposition",
                "attachment; filename="
                        + new String(resUrl.substring(resUrl.lastIndexOf("/")+1).getBytes("utf-8"),
                        "ISO8859-1"));
        response.setHeader("Content-Length", String.valueOf(bytes.length));
        IoUtil.write(response.getOutputStream(),true,bytes);
    }

}
